package org.little.v5;

import org.junit.Assert;
import org.junit.Test;
import org.little.aop.aspectj.AspectJBeforeAdvice;
import org.little.aop.aspectj.AspectJExpressionPointcut;
import org.little.aop.config.AspectInstanceFactory;
import org.little.aop.config.MethodLocatingFactory;
import org.little.beans.BeanDefinition;
import org.little.beans.ConstructorArgument;
import org.little.beans.PropertyValue;
import org.little.beans.factory.config.RuntimeBeanReference;
import org.little.beans.factory.support.DefaultBeanFactory;
import org.little.tx.TransactionManager;

import java.util.List;

/**
 * @author Tinyspot
 * @date 2022-05-30 20:20
 */
public class BeanDefinitionTest5 extends AbstractTest5 {

    @Test
    public void testAOPBean() {
        DefaultBeanFactory factory = (DefaultBeanFactory) this.getBeanFactory("little-v5.xml");

        {
            BeanDefinition beanDefinition = factory.getBeanDefinition("tx");
            Assert.assertEquals(beanDefinition.getBeanClassName(), TransactionManager.class.getName());
        }

        {
            BeanDefinition beanDefinition = factory.getBeanDefinition("placeOrder");
            Assert.assertTrue(beanDefinition.isSynthetic());
            Assert.assertEquals(beanDefinition.getBeanClass(), AspectJExpressionPointcut.class);

            PropertyValue propertyValue = beanDefinition.getPropertyValues().get(0);
            Assert.assertEquals("expression", propertyValue.getName());
            Assert.assertEquals("execution(* org.little.service.v5.*.placeOrder(..))", propertyValue.getValue());
        }

        {
            String name = AspectJBeforeAdvice.class.getName() + "#0";
            BeanDefinition beanDefinition = factory.getBeanDefinition(name);
            Assert.assertEquals(beanDefinition.getBeanClass(), AspectJBeforeAdvice.class);

            Assert.assertTrue(beanDefinition.isSynthetic());

            List<ConstructorArgument.ValueHolder> argumentValues = beanDefinition.getConstructorArgument().getArgumentValues();
            Assert.assertEquals(3, argumentValues.size());

            // 构造函数第一个参数
            {
                BeanDefinition innerBeanDefinition = (BeanDefinition) argumentValues.get(0).getValue();
                Assert.assertTrue(innerBeanDefinition.isSynthetic());
                Assert.assertEquals(innerBeanDefinition.getBeanClass(), MethodLocatingFactory.class);

                List<PropertyValue> propertyValues = innerBeanDefinition.getPropertyValues();
                Assert.assertEquals("targetBeanName", propertyValues.get(0).getName());
                Assert.assertEquals("tx", propertyValues.get(0).getValue());
                Assert.assertEquals("methodName", propertyValues.get(1).getName());
                Assert.assertEquals("start", propertyValues.get(1).getValue());
            }

            // 构造函数第二个参数
            {
                RuntimeBeanReference reference = (RuntimeBeanReference) argumentValues.get(1).getValue();
                Assert.assertEquals("placeOrder", reference.getBeanName());
            }

            // 构造函数第三个参数
            {
                BeanDefinition innerBeanDefinition = (BeanDefinition) argumentValues.get(2).getValue();
                Assert.assertTrue(innerBeanDefinition.isSynthetic());
                Assert.assertEquals(innerBeanDefinition.getBeanClass(), AspectInstanceFactory.class);

                List<PropertyValue> propertyValues = innerBeanDefinition.getPropertyValues();
                Assert.assertEquals("aspectBeanName", propertyValues.get(0).getName());
                Assert.assertEquals("tx", propertyValues.get(0).getValue());
            }
        }
    }


}
